package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.ProductDetailsMapper;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.mapper.ProductSkuMapper;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.IProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2025-02-24
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Autowired
    private ProductSkuMapper productSkuMapper;

    @Autowired
    private ProductDetailsMapper productDetailsMapper;

    @Autowired
    private SkuStockMapper skuStockMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<Product> selectProductList() {
        return baseMapper.selectProductList();
    }

    /**
     * 插入新产品信息
     * 该方法负责处理产品信息的插入，包括产品基本信息、产品SKU信息和产品详情
     * 使用事务管理，确保数据一致性
     *
     * @param product 要插入的产品对象，包含产品基本信息和关联的SKU信息
     * @return 插入操作的结果，固定返回1表示成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertProduct(Product product) {
        // 插入产品基本信息
        baseMapper.insert(product);

        // 获取产品SKU列表，并遍历每个SKU进行插入操作
        List<ProductSku> productSkuList = product.getProductSkuList();
        for (int i = 0, size = productSkuList.size(); i < size; i++) {
            ProductSku productSku = productSkuList.get(i);
            // 设置SKU编码，结合产品ID和序号生成唯一编码
            productSku.setSkuCode(product.getId() + "_" + i);
            // 关联产品ID
            productSku.setProductId(product.getId());
            // 生成SKU名称，结合产品名称和SKU规格
            String skuName = product.getName() + " " + productSku.getSkuSpec();
            productSku.setSkuName(skuName);
            // 设置SKU状态为0，表示默认状态
            productSku.setStatus(0);
            // 插入SKU信息
            productSkuMapper.insert(productSku);

            // 添加商品库存信息
            SkuStock skuStock = new SkuStock();
            // 关联SKU ID
            skuStock.setSkuId(productSku.getId());
            // 设置总库存数量
            skuStock.setTotalNum(productSku.getStockNum());
            // 设置锁定库存数量为0，表示初始没有锁定库存
            skuStock.setLockNum(0);
            // 设置可用库存数量，初始等于总库存数量
            skuStock.setAvailableNum(productSku.getStockNum());
            // 设置已售数量为0，表示初始没有销售
            skuStock.setSaleNum(0);
            // 插入库存信息
            skuStockMapper.insert(skuStock);
        }

        // 插入产品详情信息
        ProductDetails productDetails = new ProductDetails();
        // 关联产品ID
        productDetails.setProductId(product.getId());
        // 合并产品详情图片URL列表为单个字符串
        productDetails.setImageUrls(String.join(",", product.getDetailsImageUrlList()));
        // 插入产品详情信息
        productDetailsMapper.insert(productDetails);

        // 返回插入操作的结果，固定返回1表示成功
        return 1;
    }

    /**
     * 更新商品状态及其SKU状态
     *
     * @param id 商品ID
     * @param status 新的状态值
     * @return 更新操作的结果，固定返回1表示成功
     *
     * 该方法使用了事务注解，确保商品信息和SKU状态更新的原子性
     * 如果在更新过程中发生任何异常，事务将会回滚，避免数据不一致的问题
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateStatus(Long id, Integer status) {

        Product product = new Product();
        product.setId(id);
        product.setStatus(status);
        baseMapper.updateById(product);

        //更新sku的status
        productSkuMapper.update(
                null,
                new LambdaUpdateWrapper<ProductSku>()
                        .eq(ProductSku::getProductId, id)
                        .set(ProductSku::getStatus, status));

        String key = "product:sku:data";
        List<ProductSku> productSkuList = productSkuMapper.selectList(
                new LambdaQueryWrapper<ProductSku>().eq(ProductSku::getProductId, id));

        if (status == 1) {
            // 商品上架时，将 sku ID 列表放入 bitmap
            productSkuList.forEach(item -> {
                redisTemplate.opsForValue().setBit(key, item.getId(), true);
            });
        } else if (status == -1) {
            // 商品下架时，将 sku ID 列表从 bitmap 中移除
            productSkuList.forEach(item -> {
                redisTemplate.opsForValue().setBit(key, item.getId(), false);
            });
        }
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteProductByIds(List<Long> ids) {

        // 删除商品
        baseMapper.deleteBatchIds(ids);

        //查询skuIds(先查询)
        LambdaQueryWrapper<ProductSku> queryWrapper = new LambdaQueryWrapper<ProductSku>()
                .in(ProductSku::getProductId, ids)
                .select(ProductSku::getId);
        List<ProductSku> productSkuList = productSkuMapper.selectList(queryWrapper);
        List<Long> skuIds = productSkuList.stream().map(ProductSku::getId).collect(Collectors.toList());

        // 删除商品sku（再删除）
        productSkuMapper.delete(
                new LambdaQueryWrapper<ProductSku>()
                        .in(ProductSku::getProductId, ids)
        );

        //删除商品详情
        productDetailsMapper.delete(
                new LambdaQueryWrapper<ProductDetails>()
                        .in(ProductDetails::getProductId, ids)
        );

        //删除商品库存
        return skuStockMapper.delete(
                new LambdaQueryWrapper<SkuStock>()
                        .in(SkuStock::getSkuId, skuIds)
        );
    }


}
